﻿using System;
using K9Nano.EFCore.Identity;
using K9Nano.Share;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class EfCoreStartupExtensions
    {
        public static IK9NanoAppBuilder AddK9IdentityCore<TDbContext, TUser, TRole, TKey>(this IK9NanoAppBuilder builder,
            Action<IdentityOptions> identitySetupAction = null,
            Action<IdentityBuilder> configureIdentity = null)
            where TDbContext : DbContext
            where TUser : IdentityUser<TKey>
            where TRole : IdentityRole<TKey>
            where TKey : IEquatable<TKey>
        {
            var identityBuilder = builder.Services.AddIdentity<TUser, TRole>(options =>
                 {
                     // Password settings.
                     options.Password.RequireDigit = false;
                     options.Password.RequireLowercase = false;
                     options.Password.RequireNonAlphanumeric = false;
                     options.Password.RequireUppercase = false;
                     options.Password.RequiredLength = 6;
                     options.Password.RequiredUniqueChars = 1;

                     // Lockout settings.
                     options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
                     options.Lockout.MaxFailedAccessAttempts = 5;
                     options.Lockout.AllowedForNewUsers = true;

                     // User settings.
                     options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-";
                     options.User.RequireUniqueEmail = false;

                     options.ClaimsIdentity.RoleClaimType = K9SharedConstants.RoleClaimType;
                     options.ClaimsIdentity.UserNameClaimType = K9SharedConstants.UserNameClaimType;
                     options.ClaimsIdentity.UserIdClaimType = K9SharedConstants.UserIdClaimType;

                     identitySetupAction?.Invoke(options);
                 })
                  .AddErrorDescriber<LocalizedIdentityErrorDescriber>()
                  .AddEntityFrameworkStores<TDbContext>()
                  .AddDefaultTokenProviders();

            configureIdentity?.Invoke(identityBuilder);
            return builder;
        }
    }
}
